<?php

namespace Xsjosg\Zt\App\Webapp\Sixyear251014\Providers;

use Xsjosg\Zt\Core\Helper\Str;
use Xsjosg\Zt\Core\Helper\Misc;
use Xsjosg\Zt\Core\Logic\BaseLogicServiceProvider;
use Xsjosg\Zt\App\Webapp\Sixyear251014\Models\ShareUid;
use Xsjosg\Zt\App\Webapp\Sixyear251014\Models\RewardLog;


class LogicServiceProvider extends BaseLogicServiceProvider
{
    // == 注意 ==
    // 1. 操作共享数据记得加锁
    //    $this->app['locker']->lock($account);
    // 2. 数据需要同时保证写入数据库时记得使用事务
    //    $this->app['db']->connection($connection)->transaction($callback);
    // 3. 尽可能优先使用框架已提供的功能
    // 4. 命名符合psr1,psr2规范
    // 5. 方法名尽可能贴切


    const USER_SESSION_KEY = '__Sixyear251014_USER__';
    const UID_SESSION_KEY = '__Sixyear251014_UID__';
    const SERVER_SESSION_KEY = '__Sixyear251014_SERVER__';

    const PKG_ID = 'A1441';
    const GAME_ID = 'G148';
    const PRODUCT_KEY = 'u43q212j621xjng8aeybtc7f';

    const ERR_LOGIC_NOT_LOGIN = -20001;
    const ERR_LOGIC_NAME_INVALID = -20101;
    const ERR_LOGIC_PARAMS_ERROR = -20102;
    const ERR_LOGIC_LOGIN_FAIL = -20103;
    const ERR_LOGIC_NO_CHANNEL_ID = -20104;
    const ERR_LOGIC_NOT_LOGIN_UID = -20105;
    const ERR_LOGIC_ROLE_LIST_EMPTY = -20106;
    const ERR_LOGIC_ROLE_NOT_MATCH = -20107;
    const ERR_LOGIC_USER_CHECK_ERROR = -20108;
    const ERR_LOGIC_ROLE_NOT_EXIST = -20109;
    const ERR_LOGIC_API_CONFIG_ERROR = -20110;
    const ERR_LOGIC_SERVER_NOT_EXIST = -20111;
    const ERR_LOGIC_PLAYER_REVIEW_DATA_ERROR = -20112;
    const ERR_LOGIC_GET_REVIEW_SHARE_REWARD_ERROR = -20113;
    const ERR_LOGIC_GET_REVIEW_REWARD_ERROR = -20114;
    const ERR_LOGIC_GET_REVIEW_REWARD_ALREADY = -20115;
    const ERR_LOGIC_SHARE_USER_INFO_ERROR = -20116;
    const ERR_LOGIC_LINK_AND_AWARD_LIMIT_TIME = -20117;
    const ERR_LOGIC_REWARD_NOT_FINISH = -20118;
    const ERR_LOGIC_GET_SHARE_REWARD_ALREADY = -20119;
    const ERR_LOGIC_REVIEW_DATA_NOT_EXIST = -20120;
    const ERR_LOGIC_ROLE_LEVEL_NOT_ENOUGH = -20121;
    const ERR_LOGIC_ROLE_LEVEL_NOT_ENOUGH_DESC = -20122;
    const ERR_LOGIC_REWARD_ALREADY_CLAIMED = -20123;
    const ERR_LOGIC_ACTIVITY_NOT_IN_OPEN_TIME = -20124;
    protected $errors = [
        self::ERR_LOGIC_NOT_LOGIN => '登录态已失效，请先登录',
        self::ERR_LOGIC_NAME_INVALID => '名字不合法',
        self::ERR_LOGIC_PARAMS_ERROR => '参数错误',
        self::ERR_LOGIC_LOGIN_FAIL => '登录失败',
        self::ERR_LOGIC_NO_CHANNEL_ID => '没有渠道id',
        self::ERR_LOGIC_NOT_LOGIN_UID => '请先登录账号',
        self::ERR_LOGIC_ROLE_LIST_EMPTY => '角色列表为空',
        self::ERR_LOGIC_ROLE_NOT_MATCH => '不能选择不属于你的角色',
        self::ERR_LOGIC_API_CONFIG_ERROR => 'api配置不存在',
        self::ERR_LOGIC_USER_CHECK_ERROR => '未查询到您的角色，可尝试前往游戏内入口参与活动',
        self::ERR_LOGIC_ROLE_NOT_EXIST => '角色不存在',
        self::ERR_LOGIC_SERVER_NOT_EXIST => '服务器不存在',
        self::ERR_LOGIC_PLAYER_REVIEW_DATA_ERROR => '网络环境较差，请稍后再试',
        self::ERR_LOGIC_GET_REVIEW_SHARE_REWARD_ERROR => '获取分享奖励失败',
        self::ERR_LOGIC_GET_REVIEW_REWARD_ERROR => '获取奖励失败',
        self::ERR_LOGIC_GET_REVIEW_REWARD_ALREADY => '您已领取该周年奖励，请前往游戏内查看',
        self::ERR_LOGIC_SHARE_USER_INFO_ERROR => '获取分享用户信息失败',
        self::ERR_LOGIC_LINK_AND_AWARD_LIMIT_TIME => '当前时间段内不能领取奖励',
        self::ERR_LOGIC_REWARD_NOT_FINISH => '奖励相关任务未完成，无法领取奖励',
        self::ERR_LOGIC_GET_SHARE_REWARD_ALREADY => '您已领取该分享奖励，请前往游戏内查看',
        self::ERR_LOGIC_REVIEW_DATA_NOT_EXIST => '周年回顾数据不存在',
        self::ERR_LOGIC_ROLE_LEVEL_NOT_ENOUGH => '活动仅限20级以上指挥官参与',
        self::ERR_LOGIC_ROLE_LEVEL_NOT_ENOUGH_DESC => '活动仅统计截止2025-12-05前等级≥20的指挥官',
        self::ERR_LOGIC_REWARD_ALREADY_CLAIMED  => '奖励已领取',
        self::ERR_LOGIC_ACTIVITY_NOT_IN_OPEN_TIME => '活动不在开启时间内'
    ];

    private $debug = false;

      // 奖励+周年数据接口+查询角色id
    private $api = 'http://120.77.241.234:1301';

    private $serverMap = [
        501 => '测试服',
        1000 => '星火服',
        1001 => '信标服',
    ];

  
    // 根据token登录接口
    private $loginByUidApi = 'https://pre-game-role-service.kurogame.xyz';
    //private $sdkApi = 'https://pre-sdkapi.kurogame-service.com';
    private $sdkApi = 'https://sdkapi.kurogame.com';

    private $linkAndAwardLimitTime;
    private $currentTime;

    public function register()
    {
        $this->app->instance('logic', $this);
        $this->app['setting']->load();
        $this->linkAndAwardLimitTime = app('config')['app.setting.link_and_award_limit_time'];
        $this->currentTime = time();
        if (app()->environment('production')) {
            $this->api = 'http://interface.haru.kurogame.com';
            $this->loginByUidApi = 'https://game-role-service.kurogame.com';
            $this->sdkApi = 'https://sdkapi.kurogame.com';
            $this->serverMap = [
                1000 => '星火服',
                1001 => '信标服',
            ];
        }
    }

    public function redis()
    {
        return $this->app['redis']->select('webapp');
    }

    public function loginKjq(array $input)
    {
        $token = $input['token'] ?? '';
        if ($this->isDebug()) {
            $token = 'eyJhbGciOiJIUzI1NiJ9.eyJjcmVhdGVkIjoxNzA2MDAwNjAyNTE5LCJ1c2VySWQiOjEwMzc3NTkzfQ.tND5kztOA-5eA8_OMfpKPm9Xnh-R--cXFC0olfQv09c';
        }

        if (empty($token)) {
            $this->throwError(self::ERR_LOGIC_PARAMS_ERROR);
        }

        $api = "https://api.kurobbs.com";
        $path = '/user/api/openUserInfo';

        $params = [
            'pkgId' => self::PKG_ID,
            'appId' => self::GAME_ID,
            'key' => self::PRODUCT_KEY,
            'token' => $token
        ];
        $result = app('http')->get($api . $path, $params);
        if ($this->isDebug()) {
            $result = '{"code":200,"data":{"accessToken":"85ba9967-494b-3c09-bcb6-fc75b0a21eb7","cuid":"508458321","puid":"508458321","tel":"15118860607","uid":"10377593"},"msg":"请求成功","success":true}';
        }
        $resultJson = json_decode($result, true);
        $code = $resultJson['code'] ?? null;
        if ($code !== 200) {
            $this->throwError(self::ERR_LOGIC_LOGIN_FAIL);
        }
        $data = $resultJson['data'] ?? [];
        $data['puid'] = $data['cuid']; //使用cuid作为puid
        $userInfo = [
            'puid' => $data['puid'],
            'cName' => $data['cName'] ?? '',
        ];
        $this->setUserInfoFromSession($userInfo);
        $roleList = $data['roleList'] ?? [];
        if ($this->isDebug()) {
            $roleList = [
                [
                    'roleId' => 1000,
                    'roleName' => '角色1',
                ]
            ];
        }
        app('session')->put(self::SERVER_SESSION_KEY, $roleList);

        return [
            'user_info' => [
                'name' => $userInfo['cName'],
                'uid' => $userInfo['puid'],
            ],
            'accessToken' => $data['accessToken']
        ];
    }


    public function loginBySdk(array $input)
    {
        $token = $input['token'] ?? '';
        $userName = $input['username'] ?? '';
        $cuid = $input['cuid'] ?? '';
        if (empty($token) || empty($cuid)) {
            $this->throwError(self::ERR_LOGIC_PARAMS_ERROR);
        }
        $api = $this->sdkApi . '/sdkcom/v1/login/checkUserInfo.lg';
        $data = [
            'cUid' => $cuid,
            'cName' => $userName,
            'accessToken' => $token,
        ];
        $dataJson = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        $dataBase64 = base64_encode($dataJson);
        if (strlen($dataBase64) > 51) {
            $tmp = $this->changeArray(str_split($dataBase64), 33, 1, 42, 10, 50, 18, 51, 19);
            $dataBase64 = implode("", $tmp);
        }

        $body = [
            'pcode' => self::GAME_ID,
            'data' => $dataBase64,
            'timestamp' => time() . '000',
        ];
        $sign = $this->makeSign($body, self::PRODUCT_KEY);
        $body['sign'] = $sign;
        $result = app('http')->post($api, $body);
        if ($this->isDebug()) {
            $result = '{"code":0,"msg":"成功。","cUid":"507273975","cName":"U517273975A","channel":"kuro","channelId":201,"swLogin":0,"puid":507273975}';
        }
        $resultJson = json_decode($result, true);
        $code = $resultJson['code'] ?? null;
        if ($code !== 0) {
            $this->throwError(self::ERR_LOGIC_LOGIN_FAIL);
        }
        $resultJson['puid'] = $resultJson['cUid']; //使用cUid作为puid
        $userInfo = [
            'puid' => $resultJson['puid'],
            'cName' => $resultJson['cName'],
            'channel' => $resultJson['channel'],
            'channelId' => $resultJson['channelId'],
        ];
        $this->setUserInfoFromSession($userInfo);
        return [
            'user_info' => [
                'name' => $resultJson['cName'],
                'uid' => $resultJson['puid'],
            ]
        ];
    }

    public function loginByUid(array $input)
    {
        $token = $input['token'] ?? '';
        if (empty($token)) {
            $this->throwError(self::ERR_LOGIC_PARAMS_ERROR);
        }
        $method = '/token/inside/verify';
        $api = $this->loginByUidApi;
        $finalApi = $api . $method;
        $body = [
            'token' => $token,
            'devCode' => '1433223',
            'systemId' => '1',
        ];
        $result = app('http')->post($finalApi, $body);
        if ($this->isDebug()) {
            $result = '{"code":0,"msg":"请求成功","data":{"gameId":2,"serverId":501,"uid":15359227,"lv":null,"name":"指挥官"},"success":true}","status_code":200,"execute_time":0.3798,"context":null}"';
        }
        $resultJson = json_decode($result, true);
        $code = $resultJson['code'] ?? null;
        if ($code !== 0) {
            $this->throwError(self::ERR_LOGIC_LOGIN_FAIL);
        }
        $data = $resultJson['data'] ?? [];
        $roleId = $data['uid'] ?? '';
        $roleName = $data['name'] ?? '';
        $serverId = $data['serverId'] ?? '';
        $userInfo = [
            'puid' => $roleId,
            'cName' => $roleName,
        ];
        $this->setUserInfoFromSession($userInfo);
        app('session')->put(self::USER_SESSION_KEY, [
            'user_id' => $roleId,
            'role_id' => $roleId,
            'role_name' => $roleName,
            'server_id' => $serverId,
        ]);
        return [
            'user_info' => [
                'name' => $roleName,
                'uid' => $roleId,
            ]
        ];
    }


    public function loginByServerId(array $input)
    {
        $userId = $this->getUid();
        $serverId = $input['server_id'] ?? null;
        if (empty($userId) || empty($serverId)) {
            $this->throwError(self::ERR_LOGIC_PARAMS_ERROR);
        }
        $this->checkServerId($serverId);
        list($roleId, $roleName) = $this->checkServerAndUser($serverId, $userId);
        app('session')->put(self::USER_SESSION_KEY, [
            'user_id' => $userId,
            'role_id' => $roleId,
            'role_name' => $roleName,
            'server_id' => $serverId,
        ]);

        return [
            'user_info' => [
                'name' => $roleName,
                'uid' => $userId,
            ],
        ];
    }

    public function getServerList(array $input)
    {
        $serverList = $this->serverMap;
        $list = [];
        foreach ($serverList as $key => $value) {
            $tmp = [
                'name' => $value,
                'value' => $key,
            ];
            $list[] = $tmp;
        }
        return [
            'list' => $list
        ];
    }

    protected function checkServerId($serverId)
    {
        if (!isset($this->serverMap[$serverId])) {
            $this->throwError(self::ERR_LOGIC_SERVER_NOT_EXIST);
        }
    }

    public function checkServerAndUser($serverId, $userId)
    {
        return $this->queryAccountPlayer($serverId, $userId);
    }

    public function queryAccountPlayer($serverId, $userId, $channelId = '')
    {
        if ($this->isDebug()) {
            return [1001, 'test'];
        }
        $method = '/api/ExternalActivity/QueryAccountPlayer';
        $api = $this->api;
        if (empty($api)) {
            $this->throwError(self::ERR_LOGIC_API_CONFIG_ERROR);
        }
        $finalApi = $api . $method;
        $finalChannelId = empty($channelId) ? $this->getChannelId() : $channelId;
        $params = [
            'serverId' => $serverId,
            'account' => $userId,
            'channelId' => $finalChannelId,  // 渠道id
        ];
        $result = app('http')->get($finalApi, $params);
        $resulJson = json_decode($result, true);
        $code = $resulJson['code'] ?? null;
        if ($code !== 0) {
            $this->throwError(self::ERR_LOGIC_USER_CHECK_ERROR);
        }
        $data = $resulJson['data'] ?? [];
        $roleId = $data['playerId'] ?? '';
        $roleName = $data['playerName'] ?? '';
        if (empty($roleId)) {
            $this->throwError(self::ERR_LOGIC_ROLE_NOT_EXIST);
        }
        return [$roleId, $roleName];
    }


    public function loginByRoleIdAndServerId(array $input)
    {
        $userId = $this->getUid();
        $roleId = $input['role_id'] ?? null;
        $roleName = $input['role_name'] ?? null;
        $serverId = $input['server_id'] ?? null;
        if (empty($userId) || empty($serverId) || empty($roleId) || empty($roleName)) {
            $this->throwError(self::ERR_LOGIC_PARAMS_ERROR);
        }
        $sessionRoleLIst = app('session')->get(self::SERVER_SESSION_KEY);
        if ($this->isDebug()) {
            $sessionRoleLIst = [
                [
                    'roleId' => 1000,
                    'roleName' => '角色1',
                ]
            ];
        }
        if (empty($sessionRoleLIst)) {
            $this->throwError(self::ERR_LOGIC_ROLE_LIST_EMPTY);
        }
        $match = false;
        foreach ($sessionRoleLIst as $role) {
            if ($role['roleId'] == $roleId) {
                $match = true;
                break;
            }
        }
        if (!$match && app()->environment('production')) {
            $this->throwError(self::ERR_LOGIC_ROLE_NOT_MATCH);
        }

        app('session')->put(self::USER_SESSION_KEY, [
            'user_id' => $userId,
            'role_id' => $roleId,
            'role_name' => $roleName,
            'server_id' => $serverId,
        ]);
        return [
            'user_info' => [
                'name' => $roleName,
                'uid' => $userId,
            ],
        ];
    }

    public function getCurrentUser(array $input)
    {
        list($account, $roleId, $serverId, $roleName) = $this->getAccountInfo();
        return [
            'user' => [
                'user_id' => $account,
                'role_id' => $roleId,
                'server_id' => $serverId,
                'role_name' => $roleName,
                'channel_id' => $this->getChannelId(false),
            ]
        ];
    }

    public function loginOut(array $input)
    {
        app('session')->forget(self::USER_SESSION_KEY);
        app('session')->forget(self::UID_SESSION_KEY);
    }

    public function getUserConfig(array $input)
    {
        list($account, $roleId, $serverId, $roleName) = $this->getAccountInfo();
        // 查询奖励获取情况
        $getShareReward = $this->getRewardLogFromCache($roleId, $serverId, RewardLog::REWARD_TYPE_SHARE);
        $getAnnualReportReward = $this->getRewardLogFromCache($roleId, $serverId, RewardLog::REWARD_TYPE_ANNUAL_REPORT);
        //当存在记录并且状态是已领取，则表示已获取奖励  
        $hasGetShareReward = isset($getShareReward['id']) && $getShareReward['status'] == RewardLog::STATUS_CLAIMED;
        $hasGetAnnualReportReward = isset($getAnnualReportReward['id']) && $getAnnualReportReward['status'] == RewardLog::STATUS_CLAIMED;
        return [
            'user_config' => [
                'share_reward' => $hasGetShareReward,
                'annual_report_reward' => $hasGetAnnualReportReward,
            ]
        ];
    }


    public function queryPlayerReviewData(array $input)
    {
        $shareUid = $input['share_uid'] ?? '';
        if (!empty($shareUid)) {
            $userInfo = $this->getShareUserInfo($shareUid);
            $account = $userInfo['account'];
            $roleId = $userInfo['roleId'];
            $serverId = $userInfo['serverId'];
            $roleName = $userInfo['roleName'];
        } else {
            list($account, $roleId, $serverId, $roleName) = $this->getAccountInfo();
        }

        $result = $this->getPlayerReviewDataFromCache($roleId, $serverId);
        if (empty($shareUid)) { // 分享用户不记录任务
            // 判断是否存在任务记录
            $hasGetReward = $this->getRewardLogFromCache($roleId, $serverId, RewardLog::REWARD_TYPE_ANNUAL_REPORT);
            if (!isset($hasGetReward['id'])) {
                $this->insertRewardLog($roleId, $serverId, RewardLog::REWARD_TYPE_ANNUAL_REPORT);
                $this->delRewardLogCache($roleId, $serverId, RewardLog::REWARD_TYPE_ANNUAL_REPORT);
            }
        }
        return [
            'review_data' => $result
        ];
    }

    protected function getPlayerReviewDataFromCache($roleId, $serverId)
    {
        $cacheKey = app()->getId('player_review_data_' . $roleId . '_' . $serverId);
        return Misc::getValueFromCache($this->redis(), $cacheKey, 600, function () use ($roleId, $serverId) {
            return $this->getPlayerReviewDataFromApi($roleId, $serverId);
        });
    }

    public function getPlayerReviewDataFromApi($roleId, $serverId)
    {
        $method = '/api/Review/QueryPlayerReviewData';
        $api = $this->api;
        if (empty($api)) {
            $this->throwError(self::ERR_LOGIC_API_CONFIG_ERROR);
        }
        $finalApi = $api . $method;
        $params = [
            'serverId' => $serverId,
            'roleId' => $roleId,
        ];
        $header = ['Accept-Encoding' => 'gzip'];
        $result = app('http')->get($finalApi, $params,  $header);
        if ($this->isDebug()) {
            $result = '{
  "code": 0,
  "msg": "成功",
  "data": {
    "roleId": 17621679,
    "name": "天河吴彦祖",
    "headPortraitId": 9090001,
    "createTimeStamp": 1575470117,
    "existDayCount": 1723,
    "guildName": "得闲吹下⽔",
    "mainLineChapterId": 31,
    "mainLineStageId": 19,
    "mainLineStageName": "寻找四叶草的阿呆蛙",
    "assignSchedule": "野滨岬空军基地",
    "awarenessSchedule": 6,
    "awarenessTotalChapter": 6,
    "maxAbilityCharacterId": 1041004,
    "maxAbility": 7748,
    "characterCount": 53,
    "maxTrustLvName": "熟悉",
    "maxTrustLvCharacterCount": 3,
    "partnerCount": 36,
    "medalInfos": [
      {
        "id": 1,
        "time": 1592387207
      },
      {
        "id": 3,
        "time": 1676599919
      },
      {
        "id": 4,
        "time": 1698048408
      },
      {
        "id": 2,
        "time": 1699589890
      },
      {
        "id": 6,
        "time": 1721038600
      }
    ],
    "scoreTitleIdList": [
      13000001,
      13000100,
      13000600,
      13006100,
      13006800,
      13007200,
      13013004,
      13019502,
      13019401,
      13019504,
      13019501,
      13000300,
      13019601,
      13019604,
      13019603,
      13013005,
      13019602,
      13000700,
      13019608,
      13019611,
      13019619,
      13019618,
      13019621,
      13019622,
      13019623,
      13019624,
      13019626,
      13019625,
      13000500,
      13019627,
      13019628,
      13019629,
      13019630,
      13019631,
      13019638,
      13019635,
      13019639,
      13019634,
      13019641,
      13019640,
      13019645,
      13019644,
      13019647,
      13019650,
      13019651
    ],
    "fashionCollectPercent": "14.0%",
    "useActionPointCount": 78940,
    "useCoinTotalCount": 39934500,
    "onlineDayCount": 121,
    "reviewArenaChallenge": {
      "arenaHighestLevel": "英雄",
      "highestCount": 28,
      "arenaSecondLevel": "领袖",
      "secondCount": 24
    },
    "reviewCharacter": {
      "maxDormFondleMoodCharacter": 1021003,
      "maxDormFondleMoodCount": 9,
      "maxDormWorkCharacter": 1041002,
      "maxDormWorkCount": 11,
      "maxTouchCharacter": 1031002,
      "maxTouchCount": 145,
      "maxFightCharacter": 1521004,
      "maxFightCount": 682
    },
    "strongholdMaxGroupName": "渊⼭矿区",
    "reviewDraw": {
      "drawAverageCount": 58,
      "drawMaxCount": 92,
      "drawMaxCountCharacterId": 1171004,
      "drawMinCount": 13,
      "drawMinCountCharacterId": 1211003
    },
    "reviewBossSingle": {
      "bossSingleTotalScore": 53982365,
      "bossSingleMaxScore": 552210,
      "bossSingleMaxScoreBossName": "光辉⾏进者",
      "bossSingleMaxLevelName": "鏖战点"
    }
  }
}';
        }
        $resulJson = json_decode($result, true);
        $code = $resulJson['code'] ?? null;
        if ($code !== 0) {
            switch ($code) {
                case 1001:
                    // 周年回顾数据不存在错误
                    $this->throwError(self::ERR_LOGIC_ACTIVITY_NOT_IN_OPEN_TIME);
                    break;
                case 1002:
                    $this->throwError(self::ERR_LOGIC_ROLE_LEVEL_NOT_ENOUGH);
                    break;
                case 1003:
                    $this->throwError(self::ERR_LOGIC_ROLE_LEVEL_NOT_ENOUGH_DESC);
                    break;
                default:
                    $this->throwError(self::ERR_LOGIC_PLAYER_REVIEW_DATA_ERROR);
            }
        }
        $data = $resulJson['data'] ?? [];
        return $data;
    }

    public function makeFinishShare(array $input)
    {
        list($account, $roleId, $serverId, $roleName) = $this->getAccountInfo();
        app('locker')->lock('finish_share_' . $roleId);
        // 判断是否存在记录
        $hasGetReward = $this->getRewardLogFromCache($roleId, $serverId, RewardLog::REWARD_TYPE_SHARE);
        if (!isset($hasGetReward['id'])) {
            $this->insertRewardLog($roleId, $serverId, RewardLog::REWARD_TYPE_SHARE);
            $this->delRewardLogCache($roleId, $serverId, RewardLog::REWARD_TYPE_SHARE);
        }
    }

    public function getReviewReward(array $input)
    {
        list($begin, $end) = $this->getLinkAndAwardLimitTime();
        // 判断是否在时间范围内
        if (!empty($begin) && !empty($end) && ($this->currentTime > $begin && $this->currentTime < $end)) {
            $this->throwError(self::ERR_LOGIC_LINK_AND_AWARD_LIMIT_TIME);
        }
        list($account, $roleId, $serverId, $roleName) = $this->getAccountInfo();
        $hasGetReward = $this->getRewardLogFromCache($roleId, $serverId, RewardLog::REWARD_TYPE_ANNUAL_REPORT);
        if (!isset($hasGetReward['id'])) {
            $this->throwError(self::ERR_LOGIC_REWARD_NOT_FINISH);
        }
        if ($hasGetReward['status'] == RewardLog::STATUS_CLAIMED) {
            $this->throwError(self::ERR_LOGIC_GET_REVIEW_REWARD_ALREADY);
        }
        app('locker')->lock('review_reward_' . $roleId);
        $this->getReviewRewardFromApi($roleId, $serverId);
        // 更新记录状态
        RewardLog::where('id', $hasGetReward['id'])
            ->update([
                'status' => RewardLog::STATUS_CLAIMED,
                'update_time' => time()
            ]);
        $this->delRewardLogCache($roleId, $serverId, RewardLog::REWARD_TYPE_ANNUAL_REPORT);
    }

    public function getShareReward(array $input)
    {
        list($begin, $end) = $this->getLinkAndAwardLimitTime();
        // 判断是否在时间范围内
        if (!empty($begin) && !empty($end) && ($this->currentTime > $begin && $this->currentTime < $end)) {
            $this->throwError(self::ERR_LOGIC_LINK_AND_AWARD_LIMIT_TIME);
        }
        list($account, $roleId, $serverId, $roleName) = $this->getAccountInfo();
        $hasGetReward = $this->getRewardLogFromCache($roleId, $serverId, RewardLog::REWARD_TYPE_SHARE);
        if (!isset($hasGetReward['id'])) {
            $this->throwError(self::ERR_LOGIC_REWARD_NOT_FINISH);
        }
        if ($hasGetReward['status'] == RewardLog::STATUS_CLAIMED) {
            $this->throwError(self::ERR_LOGIC_GET_SHARE_REWARD_ALREADY);
        }
        app('locker')->lock('share_reward_' . $roleId);
        $this->getShareRewardFromApi($roleId, $serverId);
        // 更新记录状态
        RewardLog::where('id', $hasGetReward['id'])
            ->update([
                'status' => RewardLog::STATUS_CLAIMED,
                'update_time' => time()
            ]);
        $this->delRewardLogCache($roleId, $serverId, RewardLog::REWARD_TYPE_SHARE);
    }


    protected function delRewardLogCache($roleId, $serverId, $rewardType)
    {
        $cacheKey = app()->getId('reward_log_' . $roleId . '_' . $serverId . '_' . $rewardType);
        $this->redis()->del($cacheKey);
    }

    protected function getRewardLogFromCache($roleId, $serverId, $rewardType)
    {
        $cacheKey = app()->getId('reward_log_' . $roleId . '_' . $serverId . '_' . $rewardType);
        $result = Misc::getValueFromCache($this->redis(), $cacheKey, 600, function () use ($roleId, $serverId, $rewardType) {
            $log = RewardLog::where('user_id', $roleId)
                ->where('server_id', $serverId)
                ->where('reward_type', $rewardType)
                ->first();
            return $log ? $log->toArray() : [];
        });
        return $result;
    }

    public function getShareUid(array $input)
    {
        list($account, $roleId, $serverId, $roleName) = $this->getAccountInfo();
        $shareUid = md5($roleId . $serverId);
        $userInfo = [
            'account' => $account,
            'roleId' => $roleId,
            'serverId' => $serverId,
            'roleName' => $roleName,
        ];
        // 改为存储到share_uid表中
        $shareUidInfo = $this->getShareUidInfoFromCache($shareUid);
        if (empty($shareUidInfo)) {
            $shareUidInfo = new ShareUid();
            $shareUidInfo->share_uid = $shareUid;
            $shareUidInfo->share_info = json_encode($userInfo, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            $shareUidInfo->create_time = time();
            $shareUidInfo->update_time = time();
            $shareUidInfo->save();
        }
        // $this->redis()->setNx($shareUid, json_encode($userInfo, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
        return [
            'share_uid' => $shareUid
        ];
    }

    /**
     * 获取分享用户信息
     *
     * @param string $shareUid 分享的唯一标识
     * @return array 用户信息数组
     * @throws \Exception 如果找不到用户信息则抛出异常
     *
     * 返回的数组格式如下：
     * [
     *     'account'  => string 用户账号,
     *     'roleId'   => string 角色ID,
     *     'serverId' => string 服务器ID,
     *     'roleName' => string 角色名称
     * ]
     */
    public function getShareUserInfo($shareUid)
    {
        $shareUidInfo = $this->getShareUidInfoFromCache($shareUid);
        if (empty($shareUidInfo)) {
            $this->throwError(self::ERR_LOGIC_SHARE_USER_INFO_ERROR);
        }
        return json_decode($shareUidInfo['share_info'], true);
    }

    protected function getShareUidInfoFromCache($shareUid)
    {
        $cacheKey = app()->getId('share_uid_' . $shareUid);
        return Misc::getValueFromCache($this->redis(), $cacheKey, 600, function () use ($shareUid) {
            $result = ShareUid::where('share_uid', $shareUid)->first();
            return $result ? $result->toArray() : [];
        });
    }

    protected function delShareUidInfoCache($shareUid)
    {
        $cacheKey = app()->getId('share_uid_' . $shareUid);
        $this->redis()->del($cacheKey);
    }

    protected function insertRewardLog($roleId, $serverId, $rewardType)
    {
        RewardLog::insert([
            'user_id' => $roleId,
            'server_id' => $serverId,
            'reward_type' => $rewardType,
            'create_time' => time(),
            'update_time' => time(),
        ]);
    }

    protected function getLinkAndAwardLimitTime()
    {
        if (empty($this->linkAndAwardLimitTime)) {
            return [0, 0];
        }
        return Str::explodeRangeTime($this->linkAndAwardLimitTime, true);
    }

    // 获取周年回顾分享奖励
    public function getShareRewardFromApi($roleId, $serverId)
    {
        $method = '/api/Review/GetReviewShareReward';
        $api = $this->api;
        if (empty($api)) {
            $this->throwError(self::ERR_LOGIC_API_CONFIG_ERROR);
        }
        $finalApi = $api . $method;
        $params = [
            'serverid' => $serverId,
            'roleid' => $roleId,
        ];
        $result = app('http')->post($finalApi, $params);
        if ($this->isDebug()) {
            $result = '{
  "code": 0,
  "msg": "成功"
}';
        }
        $resulJson = json_decode($result, true);
        $code = $resulJson['code'] ?? null;
        if ($code !== 0) {
            if ($code == 1001) { // 周年回顾数据不存在错误
                $this->throwError(self::ERR_LOGIC_ACTIVITY_NOT_IN_OPEN_TIME);
            }
            if ($code == 1003) { // 周年回顾数据不存在错误
                $this->throwError(self::ERR_LOGIC_REVIEW_DATA_NOT_EXIST);
            }
            if ($code == 1004) {  // 奖励已领取
                $this->throwError(self::ERR_LOGIC_REWARD_ALREADY_CLAIMED);
            }
            $this->throwError(self::ERR_LOGIC_GET_REVIEW_SHARE_REWARD_ERROR);
        }
        return true;
    }

    // 获取周年回顾查看奖励
    public function getReviewRewardFromApi($roleId, $serverId)
    {
        $method = '/api/Review/GetReviewReward';
        $api = $this->api;
        if (empty($api)) {
            $this->throwError(self::ERR_LOGIC_API_CONFIG_ERROR);
        }
        $finalApi = $api . $method;
        $params = [
            'serverId' => $serverId,
            'roleId' => $roleId,
        ];
        $result = app('http')->post($finalApi, $params);
        if ($this->isDebug()) {
            return false;
            $result = '{
                "code": 0,
                "msg": "成功"
            }';
        }
        $resulJson = json_decode($result, true);
        $code = $resulJson['code'] ?? null;
        if ($code !== 0) {
            if ($code == 1001) { // 周年回顾数据不存在错误
                $this->throwError(self::ERR_LOGIC_ACTIVITY_NOT_IN_OPEN_TIME);
            }
            if ($code == 1003) { // 周年回顾数据不存在错误
                $this->throwError(self::ERR_LOGIC_REVIEW_DATA_NOT_EXIST);
            }
            if ($code == 1004) {  // 奖励已领取
                $this->throwError(self::ERR_LOGIC_REWARD_ALREADY_CLAIMED);
            }
            $this->throwError(self::ERR_LOGIC_GET_REVIEW_REWARD_ERROR);
        }
        return true;
    }

    protected function getCurrentLoginRoleId()
    {
        if ($this->isDebug()) {
            return "role1";
        }
        list(, $roleId) = $this->getAccountInfo();
        if (empty($roleId)) {
            $this->throwError(self::ERR_LOGIC_NOT_LOGIN_UID);
        }
        return $roleId;
    }

    protected function getAccountInfo()
    {
        $allUserInfo = app('session')->get(self::USER_SESSION_KEY);
        if ($this->isDebug()) {
            return ['user_id', 'role_id', '400', 'cc'];
        }
        if (empty($allUserInfo)) {
            $this->throwError(self::ERR_LOGIC_NOT_LOGIN);
        }
        return [
            $allUserInfo['user_id'],
            $allUserInfo['role_id'],
            $allUserInfo['server_id'],
            $allUserInfo['role_name'],
        ];
    }

    protected function getUid()
    {
        if ($this->isDebug()) {
            return "account1";
        }
        $userInfo = $this->getUserInfoFromSession();
        $uid = $userInfo['uid'] ?? '';
        if (empty($userInfo) || empty($uid)) {
            $this->throwError(self::ERR_LOGIC_NOT_LOGIN_UID);
        }
        return $uid;
    }


    protected function getUserInfoFromSession()
    {
        $userInfo = app('session')->get(self::UID_SESSION_KEY);
        // userInfo
        // {"code":0,"msg":"成功。","cUid":"507273975","cName":"U517273975A","channel":"kuro","channelId":201,"swLogin":0,"puid":507273975}
        return [
            'uid' => $userInfo['puid'] ?? '',
            'name' => $userInfo['cName'] ?? '',
            'channelId' => $userInfo['channelId'] ?? '',
        ];
    }

    protected function getChannelId($throwErr = true)
    {
        if ($this->isDebug()) {
            return "111";
        }
        $userInfo = $this->getUserInfoFromSession();
        $channelId = $userInfo['channelId'] ?? '';
        if (empty($channelId) && $throwErr) {
            $this->throwError(self::ERR_LOGIC_NO_CHANNEL_ID);
        }
        return $channelId;
    }

    protected function isDebug()
    {
        return app()->environment('development');
    }

    private function makeSign($params, $key)
    {
        ksort($params);
        $str = '';
        foreach ($params as $paramKey => $paramValue) {
            $str .= $paramKey . '=' . $paramValue . '&';
        }
        $str = $str . $key;
        $sign = strtolower(md5($str));
        return $sign;
    }

    private function changeArray($chars, ...$index)
    {
        for ($i = 1; $i < count($index); $i += 2) {
            $l = $index[$i - 1];
            $r = $index[$i];
            $c = $chars[$l];
            $chars[$l] = $chars[$r];
            $chars[$r] = $c;
        }
        return $chars;
    }

    protected function generateSign($body, $productKey)
    {
        // 实现签名生成逻辑
        ksort($body);
        $str = '';
        foreach ($body as $k => $v) {
            $str .= $k . '=' . $v . '&';
        }
        $str = $str . $productKey;
        $sign = strtolower(md5($str));
        return $sign;
    }

    public function setUserInfoFromSession($userInfo)
    {
        return app('session')->put(self::UID_SESSION_KEY, $userInfo);
    }
}
